package com.security.config.security.authentication.common;

import cn.hutool.json.JSONObject;
import cn.hutool.jwt.JWTUtil;
import com.security.constant.RedisConstant;
import com.security.domain.bo.R;
import com.security.domain.po.Account;
import com.security.utils.JsonConfigUtil;
import com.security.utils.ResponseUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 *  登录成功处理器
 *
 * @author DblSun
 */
@Component
public class MyLoginSuccessHandler implements AuthenticationSuccessHandler {

    private final StringRedisTemplate stringRedisTemplate;

    public MyLoginSuccessHandler(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request,
                                        HttpServletResponse response,
                                        Authentication authentication) throws IOException {
        Account account = (Account) authentication.getPrincipal();
        Map<String, Object> payloadMap = new HashMap<>();
        payloadMap.put("id", account.getId());
        payloadMap.put("username", account.getUsername());
        payloadMap.put("phone", account.getPhone());
        payloadMap.put("email", account.getEmail());
        payloadMap.put("roles",
                Arrays.toString( // 将 roles 转换成字符串数组，["ROLE_CEO", "ROLE_CFO"]
                        account
                                .getAuthorities().stream()
                                .map(GrantedAuthority::getAuthority).toArray()
                )
        );
        JSONObject jsonObject = new JSONObject(payloadMap, JsonConfigUtil.config); // 转换成 JSONObject 对象
        String token = JWTUtil.createToken(jsonObject, RedisConstant.TOKEN_SECRET.getBytes());
        // 讲 token 缓存到 Redis 中
        stringRedisTemplate.opsForHash()
                .put(RedisConstant.ApplicationName + RedisConstant.USER_TOKEN, account.getId().toString(), token);
        stringRedisTemplate
                .expire(RedisConstant.ApplicationName + RedisConstant.USER_TOKEN + account.getId().toString(),
                        RedisConstant.USER_TOKEN_EXPIRE, TimeUnit.HOURS);
        // 将用户信息缓存到 Redis 中
        stringRedisTemplate.opsForHash()
                .put(RedisConstant.ApplicationName + RedisConstant.USER_INFO, account.getId().toString(), payloadMap.toString());
        stringRedisTemplate
                .expire(RedisConstant.ApplicationName + RedisConstant.USER_INFO + account.getId().toString(),
                        RedisConstant.USER_INFO_EXPIRE, TimeUnit.HOURS);
        ResponseUtil.sendResponse(response, R.success("登录成功", token));
    }
}
